package com.wlstock.funi.model;

import com.maxleap.MLObject;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;

public class BaseModel implements Cloneable{

	@Override
	public String toString() {
		return super.toString();
	}

	public void  setValuesFromMlOjb(MLObject mlObj){
		Field[] fields = getFields();
		if (fields!=null){
			for (int i = 0; i < fields.length ; i++){
				fields[i].setAccessible(true);
				try {
					String fieldName = fields[i].getName();
					if ("$change".equals(fieldName)) continue;
					setMLObjValue(mlObj, fields[i]);
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void setMLObjValue(MLObject mlObj, Field field) throws IllegalAccessException {
		String fieldType = getFieldType(field);
		String fieldName = field.getName();
		if (String.class.getName().equals(fieldType)){
			field.set(this, mlObj.getString(fieldName));
		}else if (Date.class.getName().equals(fieldType)){
			field.set(this, mlObj.getDate(fieldName));
		}else if (Integer.class.getName().equals(fieldType) || "int".equals(fieldType)){
			field.set(this, mlObj.getInt(fieldName));
		}else if (Long.class.getName().equals(fieldType) || "long".equals(fieldType)){
			field.set(this, mlObj.getLong(fieldName));
		}else if (Float.class.getName().equals(fieldType)||"float".equals(fieldType)){
			field.set(this, mlObj.getNumber(fieldName).floatValue());
		} else if (Double.class.getName().equals(fieldType) || "double".equals(fieldType)){
			field.set(this, mlObj.getDouble(fieldName));
		}else if (Boolean.class.getName().equals(fieldType) || "boolean".equals(fieldType)){
			field.set(this, mlObj.getBoolean(fieldName));
		}

	}

	private String getFieldType(Field field) {
		return field.getType().getName();
	}


	public MLObject coverToMLObj(){
		MLObject mlObject = new MLObject(getClass().getSimpleName());
		Field[] fields = getFields();
		if(fields!=null){
			for(int i = 0 ; i < fields.length ; i++){
				fields[i].setAccessible(true);
				try {
					String fieldName = fields[i].getName();
					if ("$change".equals(fieldName)) continue;
					Object fieldValue = getFileldValue(fieldName);
					mlObject.put(fieldName, coverFieldValue(fieldValue));
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}

			}
		}
		return mlObject;
	}

	private Object coverFieldValue(Object fieldValue) {
		if (fieldValue == null)
			return "";
		if (fieldValue instanceof String){
			return fieldValue.toString();
		}else if (fieldValue instanceof  Integer){
			return  Integer.valueOf(fieldValue.toString());
		}else {
			return fieldValue;
		}
	}

	public Field[] getFields(){
		Field[] fields = this.getClass().getDeclaredFields();
		return fields;
	}
	
	public String[] getFieldNames(){
		Field[] fields = getFields();
		if (fields!= null) {
			String[] names = new String[fields.length];
			for(int i = 0 ; i < fields.length ; i++){
				names[i] = fields[i].getName().toUpperCase();
			}
			return names;
		}
		return null;
	}

	public boolean updateFiled(String fieldName , Object filedValue){
		Class<? extends BaseModel>  abstractClass = getClass();
		try {
			Field abstractField = abstractClass.getDeclaredField(fieldName);
			abstractField.set(this, filedValue);
			return true;
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	public String getClassName(){
		return this.getClass().getName();
	}
	
	
	public ArrayList<String> getFiledValues(){
		Field[] fields = getFields();
		if (fields!= null) {
			ArrayList<String> values = new ArrayList<String>();
			for(int i = 0 ; i < fields.length ; i++){
				fields[i].setAccessible(true);
				try {
					String fieldName = fields[i].getName();
					Object value    = getFileldValue(fieldName);
					values.add(value!=null?value.toString():"");
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					values.add("");
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return values;
		}

		
		return null;
	}

	private Object getFileldValue(String fieldName) throws InvocationTargetException, IllegalAccessException {
		String methodName = "get"+fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1, fieldName.length());
		try {
			Method method = this.getClass().getDeclaredMethod(methodName, new Class[]{});
			Object value = method.invoke(this, new Object[]{});
			return value!=null?value:null;
		} catch (NoSuchMethodException e) {
			//没有找到对应的方法的时候，去到下一个字段找,同时需要加上默认的值
			e.printStackTrace();
			return null;
		}
	}

	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}
